import cStringIO
import math
import numpy
import pylab
import subprocess

import Generator


class Simulator:
	'''
	class to manage a single simulation -- a whole bunch of them would be used to search a parameter space.
	currently: sets up, generates, runs, and plots results of a simulation.
	'''
	def __init__(self):
		self.numPyr = 2
		self.numInhib = 2
		self.dt = .25
		self.duration = 300
		self.voltVecs = None
		self.timeVec = None
	
	def readVectorFromFile(self, filename, size=1200):
		''' reads a float-valued newline-delineated vector from a file
		@param filename: file name
		@param size: size of the vector
		'''
		outVec = numpy.zeros(size, dtype=float)
		ff = open(filename, 'r')
		try:
			i = 0
			for line in ff:
				if i == size:
					break
				if line.isspace():
					continue
				outVec[i] = float(line)
				i = i + 1
	
		finally:
			ff.close()
	
		return outVec
	

	def runSim(self):
		''' runs the sim, saving the results in self.voltVecs , and the time axis in self.timeVec
		'''
		
		numCells = self.numPyr + self.numInhib
		#make an array:
		#in slot i,j  a 0 means no synapse, and a 1 means a synapse from i to j.
		#the first numPyrs cells are pyramidals, the remainder are inhibitory.
		connections = numpy.zeros(numCells**2, dtype=int).reshape(numCells,numCells)
		connections[0,1] = 1
		connections[0,2] = 1
		connections[2,1] = 1
		connections[2,3] = 1
		connections[0,3] = 1
		connections[3,1] = 1
		print connections
				
		#set up the file name for the voltage traces so we can read them back in:
		filePre = "n"
		filePost="Volts"
		gentron = Generator.Generator(self.numPyr,self.numInhib, connections, self.dt, self.duration, filePre, filePost)
		hocFile = "net_gen.hoc"
		gentron.generate()
		gentron.writeFile(hocFile)
		#run neuron:
		pstring = './special %s' % hocFile
		nrn = subprocess.call(pstring, shell=True)
		
		#read the voltage files that neuron has just output for us.
		self.timeVec = self.readVectorFromFile("timesteps.txt", gentron.numTimePoints)
		self.voltVecs = list()
		for i in range(0,numCells):
		    fstring = "%s%s%s" % (filePre, i, filePost)
		    self.voltVecs.append(self.readVectorFromFile(fstring, gentron.numTimePoints))
		    
		    

	def plotVolts(self):
		'''plots the voltage traces from each cell, if the simulation has been run. 
		'''
		if(self.timeVec != None):
			numCells = self.numInhib + self.numPyr
			for i in range(0, numCells):
			    pylab.figure(i)
			    pylab.plot(self.timeVec, self.voltVecs[i])
			    tstring = "Voltage Trace for Cell #%s" % i
			    pylab.title(tstring)
			
			
			pylab.show()
			
			
			

if __name__ == "__main__":
	import sys
	
	sim = Simulator()
	sim.runSim()
	sim.plotVolts()


		
